﻿using System.Collections.Generic;
using System.Linq;
using State;
using System.Text;
using System;

namespace Board
{
    public enum TileState { Empty, X, O };

    public class Tile
    {
        public TileState State { get; set; }
        public int Location { get; set; }
    }

    public class TttBoard
    {
        private static List<Tile> _tiles;

        public TttBoard()
        {
            _tiles = new List<Tile>();
            for (int i = 1; i <= 9; i++)
                _tiles.Add(new Tile { State = TileState.Empty, Location = i });
        }

        public TttBoard(string tileConfig)
        {
            if (tileConfig == null || tileConfig.Length != 9)
                return;
            _tiles = new List<Tile>();
            for (int i = 1; i <= 9; i++)
                _tiles.Add(new Tile {State = (TileState)Convert.ToInt32(tileConfig.Substring(i-1,1)), Location = i });

        }

        public List<Tile> Tiles
        {
            get { return _tiles; }
            set { _tiles = value; }
        }

        /// <summary>
        /// This will update the Tile given a player and location
        /// </summary>
        /// <param name="state">The current player who's turn it is</param>
        /// <param name="location">The location or Tile to update</param>
        /// <returns>An updated Tile</returns>
        public Tile UpdateTile(PlayerTurn state, int location)
        {
            var retVal = _tiles.SingleOrDefault(t => t.Location == location);

            if (retVal == null)
            {
                return new Tile();
            }

            if (retVal.State == TileState.Empty)
                retVal.State = (TileState)state;

            return retVal;
        }

        
        //      1   2   3       0   1   2
        //
        //      4   5   6       3   4   5
        //
        //      7   8   9       6   7   8
        /// <summary>
        /// This will check the winner of the game from the passed in Array
        /// </summary>
        /// <param name="state">The current TileState</param>
        /// <returns>Any Array of the Winner</returns>
        public int[] CheckWinner(TileState state)
        {
            if ((_tiles[0].State == state) && (_tiles[4].State == state) && (_tiles[8].State == state))
            {
                return new[] {1, 5, 9};
            }

            if ((_tiles[2].State == state) && (_tiles[4].State == state) && (_tiles[6].State == state))
            {
                return new[] {3, 5, 7};
            }

            if ((_tiles[0].State == state) && (_tiles[1].State == state) && (_tiles[2].State == state))
            {
                return new[] {1, 2, 3};
            }

           if ((_tiles[3].State == state) && (_tiles[4].State == state) && (_tiles[5].State == state))
            {
                return new[] {4, 5, 6};
            }

            if ((_tiles[6].State == state) && (_tiles[7].State == state) && (_tiles[8].State == state))
            {
                return new[] {7, 8, 9};
            }

            if ((_tiles[0].State == state) && (_tiles[3].State == state) && (_tiles[6].State == state))
            {
                return new[] {1, 4, 7};
            }

            if ((_tiles[1].State == state) && (_tiles[4].State == state) && (_tiles[7].State == state))
            {
                return new[] {2, 5, 8};
            }

            if ((_tiles[2].State == state) && (_tiles[5].State == state) && (_tiles[8].State == state))
            {
                return new[] {3, 6, 9};
            }
            
            // check draw
            return _tiles.Any(t => t.State == TileState.Empty) ? new[] {0} : null;
        }

        /// <summary>
        /// Overrided method for ToString() to be able to retrive 
        /// the board contents from the buttons.  This has allowed
        /// us to return it as one string.
        /// </summary>
        /// <returns>A string of the button states</returns>
        public override string ToString() 
        {
            var sb = new StringBuilder();
            foreach(var t in _tiles)
            {
                if (t == null)
                    return null;
                sb.Append(Convert.ToInt32(t.State).ToString());
            }
            return sb.ToString();
        }
    }
}
